"""
FC2提取器模块 - 函数式设计
专门处理FC2类型视频的识别、提取和验证

作者: Claude
创建时间: 2024-09-14
"""

import re
from typing import Optional, Tuple, Dict, Any, List
from functools import partial

try:
    from config.patterns import pattern_config
except ImportError:
    import sys
    import os
    sys.path.append(os.path.dirname(os.path.dirname(__file__)))
    from config.patterns import pattern_config


def extract_fc2_id_with_pattern(filename: str, pattern: str) -> Optional[str]:
    """
    使用指定模式提取FC2 ID - 纯函数设计
    
    :param filename: 文件名
    :param pattern: 正则表达式模式
    :return: 提取的ID或None
    """
    try:
        match = re.search(pattern, filename.upper())
        if match:
            return match.group(1)
    except Exception:
        pass
    return None


def is_valid_fc2_id(fc2_id: str) -> bool:
    """
    验证FC2 ID的有效性
    
    :param fc2_id: FC2 ID
    :return: 是否有效
    """
    if not fc2_id:
        return False
    
    # FC2 ID应该是7位或以上的数字
    if not fc2_id.isdigit():
        return False
    
    if len(fc2_id) < 7:
        return False
    
    # 排除明显错误的ID（如全0）
    if fc2_id == "0" * len(fc2_id):
        return False
    
    return True


def detect_fc2_type(filename: str) -> Tuple[bool, Optional[str]]:
    """
    检测是否为FC2类型并提取ID
    
    :param filename: 清理后的文件名
    :return: (是否为FC2, 提取的ID)
    """
    fc2_patterns = pattern_config.get_fc2_patterns()
    
    # 按优先级尝试每个模式
    for pattern_config_item in fc2_patterns:
        extracted_id = extract_fc2_id_with_pattern(filename, pattern_config_item.pattern)
        
        if extracted_id and is_valid_fc2_id(extracted_id):
            return True, extracted_id
    
    return False, None


def extract_fc2_metadata(filename: str) -> Dict[str, Any]:
    """
    提取FC2视频的元数据信息
    
    :param filename: 文件名
    :return: 元数据字典
    """
    metadata = {
        'has_subtitle': False,
        'cd_number': None,
        'is_4k': False,
        'quality_info': None
    }
    
    filename_upper = filename.upper()
    
    # 检测字幕标记
    metadata['has_subtitle'] = bool(re.search(r'[-_]C(?:\.|$)', filename_upper))
    
    # 检测4K标记
    metadata['is_4k'] = bool(re.search(r'[-_]4K', filename_upper))
    
    # 检测CD分段信息
    # 只检测明确的CD标记，避免误判主要ID中的数字
    cd_match = re.search(r'[-_]CD(\d+)', filename_upper)
    if cd_match:
        cd_num = int(cd_match.group(1))
        if 1 <= cd_num <= 20:  # 合理范围
            metadata['cd_number'] = cd_num
    
    # 检测质量信息
    quality_patterns = ['FHD', '4K', 'HD']
    for quality in quality_patterns:
        if quality in filename_upper:
            metadata['quality_info'] = quality
            break
    
    return metadata


def standardize_fc2_filename(fc2_id: str, metadata: Dict[str, Any]) -> str:
    """
    标准化FC2文件名
    
    :param fc2_id: FC2 ID
    :param metadata: 元数据信息
    :return: 标准化的文件名（不含扩展名）
    """
    # 基础格式：FC2-ID
    base_name = f"FC2-{fc2_id}"
    
    # 添加后缀
    suffix_parts = []
    
    # 4K标记
    if metadata.get('is_4k', False):
        suffix_parts.append('4K')
    
    # CD分段标记
    if metadata.get('cd_number'):
        suffix_parts.append(f"CD{metadata['cd_number']}")
    
    # 字幕标记
    if metadata.get('has_subtitle', False):
        suffix_parts.append('C')
    
    # 组合最终文件名
    if suffix_parts:
        final_name = f"{base_name}-{'-'.join(suffix_parts)}"
    else:
        final_name = base_name
    
    return final_name.upper()


def validate_fc2_result(standardized_name: str) -> bool:
    """
    验证FC2标准化结果
    
    :param standardized_name: 标准化后的文件名
    :return: 验证是否通过
    """
    # FC2格式验证：FC2-数字
    base_pattern = r'^FC2-\d{7,}'
    
    if not re.match(base_pattern, standardized_name):
        return False
    
    # 后缀验证（可选的-4K、-CD数字、-C）
    suffix_pattern = r'^FC2-\d{7,}(?:-(?:4K|CD\d+|C))*$'
    
    return bool(re.match(suffix_pattern, standardized_name))


def process_fc2_filename(original_filename: str, cleaned_filename: str) -> Optional[Tuple[str, Dict[str, Any]]]:
    """
    处理FC2文件名的主函数 - 完整流水线
    
    :param original_filename: 原始文件名
    :param cleaned_filename: 清理后的文件名
    :return: (标准化文件名, 元数据) 或 None
    """
    # 步骤1: 检测是否为FC2类型
    is_fc2, fc2_id = detect_fc2_type(cleaned_filename)
    
    if not is_fc2 or not fc2_id:
        return None
    
    # 步骤2: 提取元数据
    metadata = extract_fc2_metadata(cleaned_filename)
    metadata['video_type'] = 'FC2'
    metadata['extracted_id'] = fc2_id
    metadata['original_filename'] = original_filename
    
    # 步骤3: 标准化文件名
    standardized_name = standardize_fc2_filename(fc2_id, metadata)
    
    # 步骤4: 验证结果
    if not validate_fc2_result(standardized_name):
        return None
    
    metadata['is_valid'] = True
    
    return standardized_name, metadata


def batch_process_fc2_filenames(filename_list: List[Tuple[str, str]]) -> List[Tuple[str, Optional[str], Optional[Dict[str, Any]]]]:
    """
    批量处理FC2文件名
    
    :param filename_list: [(原始文件名, 清理后文件名), ...]
    :return: [(原始文件名, 标准化文件名或None, 元数据或None), ...]
    """
    def process_single(filename_pair: Tuple[str, str]) -> Tuple[str, Optional[str], Optional[Dict[str, Any]]]:
        """处理单个文件名的映射函数"""
        original, cleaned = filename_pair
        result = process_fc2_filename(original, cleaned)
        
        if result:
            standardized, metadata = result
            return original, standardized, metadata
        else:
            return original, None, None
    
    # 使用函数式编程的map进行批量处理
    return list(map(process_single, filename_list))


# 偏函数工厂 - 提供便捷的配置化接口
def create_fc2_extractor_with_config(min_id_length: int = 7) -> callable:
    """
    创建配置化的FC2提取器
    
    :param min_id_length: 最小ID长度
    :return: 配置好的提取器函数
    """
    def configured_validator(fc2_id: str) -> bool:
        return is_valid_fc2_id(fc2_id) and len(fc2_id) >= min_id_length
    
    return partial(process_fc2_filename)


# 导出的函数式接口
__all__ = [
    "detect_fc2_type",
    "process_fc2_filename",
    "batch_process_fc2_filenames",
    "validate_fc2_result",
    "create_fc2_extractor_with_config"
]